package com.itlong.cloud.controller.miniprogram;

import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.abstracts.BaseController;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.constants.LogDescConstant;
import com.itlong.cloud.enumerate.PaySourceEnum;
import com.itlong.cloud.enumerate.ThirdPartPayTypeEnum;
import com.itlong.cloud.enumerate.ecode.AppErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.MiniProgramErrorCodeEnum;
import com.itlong.cloud.paymenthub.IAccountBalanceServiceClient;
import com.itlong.cloud.paymenthub.IWeChatPayServiceClient;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.utils.encrypt.Md5EncryptUtil;
import com.itlong.cloud.utils.encrypt.UserTokenUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.math.BigDecimal;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * <desc>
 *     微信小程序支付控制器
 * </desc>
 *
 * @create  2019/05/27
 */
@RestController
@RequestMapping("/mini/pay")
@RefreshScope
public class MiniprogramPayController extends BaseController{

    private static final Logger LOG = LoggerFactory.getLogger(MiniprogramPayController.class);

    //解密用
    @Value("${" + PlatformConstants.MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY + "}")
    public String MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY;

    //解析userId用
    @Value("${" + PlatformConstants.MINI_PROGRAM_USER_TOKEN_KEY + "}")
    public String MINI_PROGRAM_USER_TOKEN_KEY;

    @Autowired
    IWeChatPayServiceClient wechatPayServiceClient;

    @Autowired
    IAccountBalanceServiceClient iAccountBalanceServiceClient;

    /**
     * <desc>
     *      小程序支付-调微信后台统一下单接口/商户后台保存订单
     * <desc/>
     *
     * @param total 支付金额
     * @param billsId 账单编号
     * @param feeType 缴费类型 1物业费 2维修费 3临时车缴费 4月卡缴费
     * @return 标准化响应结果
     * @author Juguang.S
     * @createDate 2019/05/29
     */
    @LoggerInfo(operateDesc = LogDescConstant.WECHAT_PAYMENT_ORDER)
    @PostMapping(path = "/order")
    @ResponseBody
    public Object saveOrder(String total, String billsId, String openId, String createTime, String sign, String feeType,String token) {
        //LOG.info("======saveOrder参数：total：" + total);
        try {
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            total=request.getAttribute("total")==null?null:request.getAttribute("total").toString();
            billsId=request.getAttribute("billsId")==null?null:request.getAttribute("billsId").toString();
            openId=request.getAttribute("openId")==null?null:request.getAttribute("openId").toString();
            token=request.getAttribute("token")==null?null:request.getAttribute("token").toString();
            createTime=request.getAttribute("createTime")==null?null:request.getAttribute("createTime").toString();
            sign=request.getAttribute("sign")==null?null:request.getAttribute("sign").toString();
            feeType=request.getAttribute("feeType")==null?null:request.getAttribute("feeType").toString();
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("total", total);
            params.put("feeType", feeType);
            params.put("billsId", billsId);
            params.put("createTime", createTime);
            params.put("openId", openId);
            if (!Md5EncryptUtil.checkAppSignValue(params, sign, MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            } else if (StringUtils.isBlank(total) || StringUtils.isBlank(createTime) || StringUtils.isBlank(billsId) || StringUtils.isBlank(openId)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            } else if (Double.parseDouble(total) <= 0) {
                return new MessageVO(AppErrorCodeEnum.TRADE_AMCOUNT_ERR.getErrorCode());
            }
            //校验第三方支付管理微信支付是否被禁用
            if (wechatPayServiceClient.getThirdPayStatus(ThirdPartPayTypeEnum.WECHAT_PAY.getType()) == 0) {
                return new MessageVO(AppErrorCodeEnum.NOT_ALLOWED_WEICHAT_TRADE.getErrorCode());
            }
            //查询该账单是否已经被完成
            if (wechatPayServiceClient.getBillStatus(billsId) > 0) {
                return new MessageVO(AppErrorCodeEnum.BILL_PAY_SUCCESS.getErrorCode());
            }
            //查询账单的金额，校验入参金额
            String totalDB = wechatPayServiceClient.getBillTotal(billsId,1);
            if(StringUtils.isNotEmpty(totalDB)){
                BigDecimal totalCheck = new BigDecimal(total);
                BigDecimal totalDBCheck = new BigDecimal(totalDB);
                if(totalCheck.compareTo(totalDBCheck)!=0){
                    return new MessageVO(AppErrorCodeEnum.BILL_PAY_TOTAL_IS_NOT_SAME.getErrorCode());
                }
            }
            //解密拿到userId
            String userId = UserTokenUtil.tokenDecrypt(token, MINI_PROGRAM_USER_TOKEN_KEY);

            Map<Object, Object> resultMap = wechatPayServiceClient.saveOrder(total, userId, billsId, feeType, openId, PaySourceEnum.WECHAT_MINI_SOURCE.getType(),null,null,request.getRemoteAddr(),null,null);
            if (resultMap.size() == 9 || resultMap.size() == 8) {
                return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), resultMap);
            } else {
                return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), resultMap);
            }

        } catch (Exception e) {
            throw new DataAccessException("【公众号_微信支付】API返回的数据异常", e);
        }
    }

    /**
     * <desc>
     *      检测订单状态是否为完成
     * <desc/>
     *
     * @param
     * @return  标准化响应结果
     * @author Juguang.S
     * @createDate 2019/05/29
     */
    @ResponseBody
    @RequestMapping("/checkTradeSuccess")
    public Object checkTradeSuccess(String createTime,String sign,String billsId,String tradeId) {
        try {
            HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            createTime=request.getAttribute("createTime")==null?null:request.getAttribute("createTime").toString();
            billsId=request.getAttribute("billsId")==null?null:request.getAttribute("billsId").toString();
            sign=request.getAttribute("sign")==null?null:request.getAttribute("sign").toString();
            tradeId=request.getAttribute("tradeId")==null?null:request.getAttribute("tradeId").toString();

            //LOG.info("【小程序检测订单状态是否为完成】"+"billsId:"+billsId+"----tradeId:"+tradeId);
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("billsId",billsId);
            params.put("tradeId",tradeId);
            if (!Md5EncryptUtil.checkAppSignValue(params, sign,MINI_PROGRAM_REQUEST_PARAMS_ENCRYPT_KEY)){
                return new MessageVO(MiniProgramErrorCodeEnum.MINI_PROGRAM_SIGN_ERR.getErrorCode());
            }else if (StringUtils.isBlank(billsId)||StringUtils.isBlank(tradeId)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            Map<String,Object> map = new HashMap<>();
            if(iAccountBalanceServiceClient.checkTradeSuccess(billsId,"",tradeId)){
                //2代表订单支付成功  1代表支付未成功
                map.put("paymentStatus","2");
            }else {
                map.put("paymentStatus","1");
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),map);
        } catch (Exception e) {
            throw new DataAccessException("【微信】检测订单状态是否为完成失败", e);
        }
    }
}
